home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Panel Editor / Source / PanelEditorUtils.cpp < prev    next >
Encoding:
Text File  |  1995-12-08  |  16.3 KB  |  654 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        PanelEditorUtils.cpp
  3.  
  4.     Contains:    PanelEditor utility functions & classes
  5.  
  6.     Written by:    Steve Smith
  7.  
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. // -- Compiler/Preprocessor Switches --
  12.  
  13. #ifndef _COMPILERDEFS_
  14. #include "CompDefs.h"
  15. #endif
  16.  
  17. // -- OpenDoc Utilities --
  18.  
  19. #ifndef _EXCEPT_
  20. // Exceptions define several important macros (ie. CHECKENV)
  21. // which are used in the SOM method dispatch glue. If Except.h
  22. // is not included early enough, exceptions may not be thrown
  23. // correctly when returning from a SOM method with "ev" parameter set.
  24. #include <Except.h>
  25. #endif
  26.  
  27. // --- PanelEditor Includes ---
  28.  
  29. #ifndef _PANELEDITORUTILS_
  30. #include "PanelEditorUtils.h"
  31. #endif
  32.  
  33. #ifndef _PANELEDITORDEF_
  34. #include "PanelEditorDef.h"
  35. #endif
  36.  
  37. #ifndef _SAMPLECOLLECTIONS_
  38. #include "SampleCollections.h"
  39. #endif
  40.  
  41. #ifndef _PANELEDITORGLOBALS_
  42. #include "PanelEditorGlobals.h"
  43. #endif
  44.  
  45. // --- OpenDoc Includes ---
  46.  
  47. #ifndef _ODTYPES_
  48. #include <ODTypes.h>
  49. #endif
  50.  
  51. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  52. #include <StdDefs.xh>
  53. #endif
  54.  
  55. #ifndef SOM_ODFrame_xh
  56. #include <Frame.xh>
  57. #endif
  58.  
  59. #ifndef SOM_ODDraft_xh
  60. #include <Draft.xh>
  61. #endif
  62.  
  63. #ifndef SOM_ODDocument_xh
  64. #include <Document.xh>
  65. #endif
  66.  
  67. #ifndef SOM_ODContainer_xh
  68. #include <ODCtr.xh>
  69. #endif
  70.  
  71. #ifndef SOM_ODNameSpaceManager_xh
  72. #include <NmSpcMg.xh>
  73. #endif
  74.  
  75. #ifndef SOM_ODValueNameSpace_xh
  76. #include <ValueNS.xh>
  77. #endif
  78.  
  79. // -- OpenDoc Utilities --
  80.  
  81. #ifndef _BNDNSUTL_
  82. #include <BndNSUtl.h>
  83. #endif
  84.  
  85. #ifndef _DOCUTILS_
  86. #include <DocUtils.h>
  87. #endif
  88.  
  89. #ifndef _ODDEBUG_
  90. #include <ODDebug.h>
  91. #endif
  92.  
  93. #ifndef _ODNEW_
  94. #include <ODNew.h>
  95. #endif
  96.  
  97. #ifndef _ODUTILS_
  98. #include <ODUtils.h>
  99. #endif
  100.  
  101. #ifndef _STDTYPIO_
  102. #include <StdTypIO.h>
  103. #endif
  104.  
  105. #ifndef _STORUTIL_
  106. #include <StorUtil.h>
  107. #endif
  108.  
  109. #ifndef _TEMPOBJ_
  110. #include <TempObj.h>
  111. #endif
  112.  
  113. #ifndef _TEMPITER_
  114. #include <TempIter.h>
  115. #endif
  116.  
  117. #ifndef _USERSRCM_
  118. #include <UseRsrcM.h>
  119. #endif
  120.  
  121. // --- Macintosh Includes ---
  122.  
  123. #ifndef __RESOURCES__
  124. #include <Resources.h>
  125. #endif
  126.  
  127. #ifndef __GXMATH__
  128. #include <GXMath.h>
  129. #endif
  130.  
  131. #ifndef __SCRIPT__
  132. #include <Script.h>
  133. #endif
  134.  
  135. #pragma segment PanelEditorUtilities
  136.  
  137. //=========================================================================
  138. // Utility Classes
  139. //=========================================================================
  140.  
  141. //-------------------------------------------------------------------------
  142. // CFrameProxy
  143. //-------------------------------------------------------------------------
  144.  
  145. //-------------------------------------------------------------------------
  146. // CFrameProxy::SetFrame
  147. //
  148. // Description:        The code will not affect the proxy fields unless it can
  149. //                     successfully acquire the incoming frame, it's id, and
  150. //                    the draft the frame lives in. If something goes wrong,
  151. //                    the proxy remains unchanged.
  152. //-------------------------------------------------------------------------
  153.  
  154. void CFrameProxy::SetFrame(Environment* ev, ODFrame* frame)
  155. {
  156.     ASSERT(frame!=kODNULL, kODErrIllegalNullFrameInput);
  157.     
  158.     ODID id;
  159.     ODDraft* draft;
  160.     
  161.     // Using the temp object will cleanup the incoming
  162.     // frame's refcount if something goes wrong.
  163.     frame->Acquire(ev);
  164.     TempODFrame tFrame = frame;
  165.     
  166.     // Perform all the operations that can fail first.
  167.     TempODPart tPart = frame->AcquirePart(ev);
  168.     id = frame->GetID(ev);
  169.     draft = ODGetDraft(ev, tPart);
  170.     ODReleaseObject(ev, fFrame);
  171.  
  172.     // If all went well, set the proxy fields.
  173.     fFrame = tFrame.DontRelease();
  174.     fID = id;
  175.     fDraft = draft;
  176. }
  177.  
  178. //-------------------------------------------------------------------------
  179. // CFrameProxy::GetFrame
  180. //-------------------------------------------------------------------------
  181.  
  182. ODFrame* CFrameProxy::GetFrame(Environment* ev)
  183. {
  184.     if ( fFrame == kODNULL )
  185.     {
  186.         TRY
  187.             TempODFrame tFrame = fDraft->AcquireFrame(ev, fID);
  188.             this->SetFrame(ev, tFrame);
  189.         CATCH_ALL
  190.             fFrame = kODNULL;
  191.             fID = kODNULLID;
  192.         ENDTRY
  193.     }
  194.     return fFrame;
  195. }
  196.  
  197. //-------------------------------------------------------------------------
  198. // CFrameProxy::FrameIsLoaded
  199. //-------------------------------------------------------------------------
  200.  
  201. ODBoolean CFrameProxy::FrameIsLoaded(Environment* ev)
  202. {
  203.     ODBoolean loaded = (fFrame != kODNULL ||
  204.                         fDraft->IsValidID(ev, fID));
  205.     return loaded;
  206. }
  207.  
  208. //-------------------------------------------------------------------------
  209. // CFrameProxy::Purge
  210. //-------------------------------------------------------------------------
  211.  
  212. void CFrameProxy::Purge(Environment* ev)
  213. {
  214.     if ( fFrame != kODNULL )
  215.     {
  216.         fID = fFrame->GetID(ev);
  217.         ODReleaseObject(ev,fFrame);
  218.     }
  219. }
  220.  
  221. //-------------------------------------------------------------------------
  222. // CDrawingText
  223. //-------------------------------------------------------------------------
  224.  
  225. //-------------------------------------------------------------------------
  226. // CDrawingText::CDrawingText
  227. //-------------------------------------------------------------------------
  228.  
  229. CDrawingText::CDrawingText()
  230. {
  231.     GetPort(&port);
  232.     
  233.     // Save the text settings in the port.
  234.     font = port->txFont;
  235.     face = port->txFace;
  236.     size = port->txSize;
  237.     
  238.     // Change the text settings for drawing the icon names.
  239.     TextFont(gGlobals->fScriptFont);
  240.     TextFace(normal);
  241.     TextSize(gGlobals->fScriptFontSize);
  242. }
  243.  
  244. //-------------------------------------------------------------------------
  245. // CDrawingText::CDrawingText
  246. //-------------------------------------------------------------------------
  247.  
  248. CDrawingText::CDrawingText(ODIText* text)
  249. {
  250.     GetPort(&port);
  251.     
  252.     // Save the text settings in the port.
  253.     font = port->txFont;
  254.     face = port->txFace;
  255.     size = port->txSize;
  256.     
  257.     ODSShort fontNum;
  258.     ODUShort fontSize;
  259.     
  260.     // Using the script code in the ODIText object, determine which
  261.     // font and size to use for drawing.
  262.     GetScriptFontSize(somGetGlobalEnvironment(), GetITextScriptCode(text),
  263.                             &fontNum, &fontSize);
  264.     
  265.     // Change the text settings for drawing the icon names.
  266.     TextFont(fontNum);
  267.     TextFace(normal);
  268.     TextSize(fontSize);
  269. }
  270.  
  271. //-------------------------------------------------------------------------
  272. // CDrawingText::~CDrawingText
  273. //-------------------------------------------------------------------------
  274.  
  275. CDrawingText::~CDrawingText()
  276. {
  277.     SetPort(port);
  278.     
  279.     // Restore the port text settings.
  280.     TextFont(font);
  281.     TextFace(face);
  282.     TextSize(size);
  283. }
  284.  
  285. //====================================================================
  286. // Utility Functions
  287. //====================================================================
  288.  
  289. //--------------------------------------------------------------------
  290. // GetPartName
  291. //--------------------------------------------------------------------
  292.  
  293. ODIText* GetPartName(Environment* ev, ODPart* part, ODType category)
  294. {
  295.     ASSERT(part != kODNULL, kODErrIllegalNullPartInput);
  296.  
  297.     // Get the root part of the document.
  298.     ODDraft* draft = ODGetDraft(ev,part);
  299.     TempODPart rootPart = ODAcquireRootPartOfDraft(ev, draft);
  300.     
  301.     // Get the part name.
  302.     // If we can't get a valid name for the part, we generate one using
  303.     // the user visible category name of the part's category.
  304.     TempODIText partName = ODGetITextProp(ev, part->GetStorageUnit(ev), 
  305.                                          kODPropName, kODMacIText, kODNULL);
  306.     
  307.     // If the part is the root of the document, return the name of the file.
  308.     if ( ODObjectsAreEqual(ev, part, rootPart) )
  309.     {
  310.         ODContainer* container = draft->GetDocument(ev)->GetContainer(ev);
  311.         TempPlatformFile file = GetPlatformFileFromContainer(ev, container);
  312.  
  313.         TempODIText fileName = file->GetName();
  314.         
  315.         // Test the file name against the part name. If the two are equivalent
  316.         // (not equal), then use the part name.
  317.         if ( !NamesAreEquivalent(ev, fileName, partName) )
  318.         {
  319.             // If the names are different, return the file name.
  320.             // (This code transfers the ODIText object to the partName tempobj)
  321.             DisposeIText(partName.DontDelete());
  322.             partName = fileName.DontDelete();
  323.         }
  324.     }
  325.     else
  326.     {
  327.         if ( (partName == kODNULL) || (GetITextStringLength(partName) == 0) )
  328.         {
  329.             ODIText* categoryName;
  330.             ODNameSpaceManager* nsMgr = ODGetSession(ev,part)->GetNameSpaceManager(ev);
  331.             
  332.             // Get the category string from the category name space.
  333.             if ( GetUserCatFromCat(nsMgr, category, &categoryName) )
  334.             {
  335.                 // If we successfully retrieved the category user string, return it.
  336.                 // (This code transfers the ODIText object to the partName tempobj)
  337.                 DisposeIText(partName.DontDelete());
  338.                 partName = categoryName;
  339.             }
  340.             else
  341.             {
  342.     #if ODDebug
  343.                 // This should never happen. Check NMAP for errors.
  344.                 DebugStr("\pCategory NMAP bad, or Preferences corrupted.");
  345.     #else
  346.                 THROW(kODErrInvalidNSType);
  347.     #endif
  348.             }
  349.         }
  350.     }
  351.     
  352.     return partName.DontDelete();
  353. }
  354.  
  355. //--------------------------------------------------------------------
  356. // NamesAreEquivalent
  357. //--------------------------------------------------------------------
  358.  
  359. ODBoolean NamesAreEquivalent(Environment* ev, ODIText* fileName,
  360.                                         ODIText* partName)
  361. {
  362.     Str255 fileStr;
  363.     Str255 partStr;
  364.     
  365.     // If the strings are in different languages, we're done.
  366.     if ( (GetITextScriptCode(fileName) != GetITextScriptCode(partName)) ||
  367.             GetITextLangCode(fileName) != GetITextLangCode(partName) )
  368.         return kODFalse;
  369.     
  370.     GetITextPString(fileName, fileStr);
  371.     GetITextPString(partName, partStr);
  372.  
  373.     // If the string lengths are different, we're done.
  374.     if ( fileStr[0] != partStr[0] )
  375.         return kODFalse;
  376.  
  377.     // Return the Toolbox string equivalence test.
  378.     return EqualString(fileStr,partStr,kODTrue,kODTrue);
  379. }
  380.  
  381. //--------------------------------------------------------------------
  382. // GetEditorScriptLanguage
  383. //--------------------------------------------------------------------
  384.  
  385. void GetEditorScriptLanguage(Environment* ev, ODScriptCode* script,
  386.                                         ODLangCode* language)
  387. {
  388.     long region;
  389.     
  390.     ODSLong rfRef;
  391.     rfRef = BeginUsingLibraryResources();
  392.     {
  393.         Handle versHdl = Get1Resource('vers', 1);
  394.         
  395.         // Get the region code of the editor, otherwise use the
  396.         // region code the of the primary system script.
  397.         
  398.         if ( versHdl )
  399.         {
  400.             region = (long)(*(VersRecHndl)versHdl)->countryCode;
  401.             ReleaseResource(versHdl);
  402.         }
  403.         else
  404.         {
  405.             region = GetScriptManagerVariable(smRegionCode);
  406.         }
  407.         
  408.         // Spanish & Japanese are not actually supported by the editor.
  409.         // They are provided as examples of how to add recognition of
  410.         // additional regions (see Script.h for region codes).
  411.         
  412.         switch ((short)region) {
  413.             case verUS:
  414.                 *script = smRoman;
  415.                 *language = langEnglish;
  416.                 break;
  417.             case verSpain:
  418.                 *script = smRoman;
  419.                 *language = langSpanish;
  420.                 break;
  421.             case verJapan:
  422.                 *script = smJapanese;
  423.                 *language = langJapanese;
  424.                 break;
  425.             default:
  426.                 *script = smRoman;
  427.                 *language = langEnglish;
  428.         }                
  429.     }
  430.     EndUsingLibraryResources(rfRef);
  431. }
  432.  
  433. //--------------------------------------------------------------------
  434. // GetScriptFontSize
  435. //--------------------------------------------------------------------
  436.  
  437. void GetScriptFontSize(Environment* ev, ODScriptCode script, ODSShort* fontNum,
  438.                                         ODUShort* fontSize)
  439. {
  440.     long result = GetScriptVariable(script, smScriptSmallFondSize);
  441.     
  442.     *fontNum = (ODSShort) HiWord(result);
  443.     *fontSize = (ODUShort) LoWord(result);
  444. }
  445.  
  446. //--------------------------------------------------------------------
  447. // FixedToIntRect
  448. //--------------------------------------------------------------------
  449.  
  450. void FixedToIntRect(ODRect& fixedRect, Rect& intRect)
  451. {
  452.     intRect.top        = FixedToInt(fixedRect.top);
  453.     intRect.left    = FixedToInt(fixedRect.left);
  454.     intRect.bottom    = FixedToInt(fixedRect.bottom);
  455.     intRect.right    = FixedToInt(fixedRect.right);
  456. }
  457.  
  458. //--------------------------------------------------------------------
  459. // IntToFixedRect
  460. //--------------------------------------------------------------------
  461.  
  462. void IntToFixedRect(Rect& intRect, ODRect& fixedRect)
  463. {
  464.     fixedRect.left        = ff(intRect.left);
  465.     fixedRect.top        = ff(intRect.top);
  466.     fixedRect.right        = ff(intRect.right);
  467.     fixedRect.bottom    = ff(intRect.bottom);
  468. }
  469.  
  470. //--------------------------------------------------------------------
  471. // LoadThumbnail
  472. //--------------------------------------------------------------------
  473.  
  474. void LoadThumbnail(Environment* ev, Handle* thumbnail)
  475. {
  476.     if ( *thumbnail ) return;
  477.     
  478.     ODSLong rfNum = BeginUsingLibraryResources();
  479.     {
  480.         *thumbnail = (Handle) GetPicture(kThumbnailPicture);
  481.     }
  482.     EndUsingLibraryResources(rfNum);
  483. }
  484.  
  485. //--------------------------------------------------------------------
  486. // TilePartWindow
  487. //--------------------------------------------------------------------
  488.  
  489. Rect TilePartWindow(Environment* ev, Rect* facetBounds, Rect* partWindowBounds)
  490. {
  491.     const short    kWindowTilingConst    = 20;
  492.     const short kLeftToRight        = 0;
  493.     const short kRightToLeft        = -1;
  494.     
  495.     short direction;
  496.     
  497.     // Get the direction for the primary script system running on this machine.
  498.     // (Right-to-Left or Left-to-Right)
  499.     direction = GetSysDirection();
  500.     
  501.     // The child window should be tiled from the topLeft corner of the 
  502.     // active facet who's frame is being opened.
  503.     if ( direction == kLeftToRight )
  504.     {
  505.         // Position the window rect at the top/left corner of the facet.
  506.         OffsetRect(partWindowBounds, facetBounds->left, facetBounds->top);
  507.         // Now tile the window rect down and to the right.
  508.         OffsetRect(partWindowBounds, kWindowTilingConst, kWindowTilingConst);
  509.     }
  510.     // The child window should be tiled from the topRight corner of the 
  511.     // active facet who's frame is being opened.
  512.     else if ( direction == kRightToLeft )
  513.     {
  514.         // Position the window rect at the top/right corner of the facet.
  515.         OffsetRect(partWindowBounds, (partWindowBounds->right - facetBounds->right),
  516.                     facetBounds->top);
  517.         // Now tile the window rect down and to the left.
  518.         OffsetRect(partWindowBounds, -kWindowTilingConst, kWindowTilingConst);
  519.     }
  520.     
  521.     return *partWindowBounds;
  522. }
  523.  
  524. //--------------------------------------------------------------------
  525. // CountFacets
  526. //--------------------------------------------------------------------
  527.  
  528. ODUShort CountFramesFacets(Environment* ev, ODFrame* frame)
  529. {
  530.     ODUShort facetCount = 0;
  531.     ODFacet* facet;
  532.     
  533.     TempODFrameFacetIterator ffiter(ev, frame);
  534.     facet = ffiter.First();
  535.     while ( ffiter.IsNotComplete() )
  536.     {
  537.         facetCount++;
  538.         facet = ffiter.Next();
  539.     }
  540.     
  541.     return facetCount;
  542. }
  543.  
  544. //------------------------------------------------------------------------------
  545. // RemoveFacets (from BndNSUtl.cpp)
  546. //------------------------------------------------------------------------------
  547.  
  548. void RemoveFacetsFromFrame(Environment* ev, ODFrame* frame)
  549. {
  550.     CList* list = new CList;
  551.     ODFacet* facet;
  552.     
  553.     TempODFrameFacetIterator fiter(ev, frame);
  554.     for ( facet = fiter.First(); fiter.IsNotComplete();
  555.             facet = fiter.Next() )
  556.     {
  557.         list->Add((ODPtr)facet);
  558.     }
  559.     
  560.     CListIterator liter(list);
  561.     for ( facet = (ODFacet*)liter.First();
  562.             liter.IsNotComplete();
  563.             facet = (ODFacet*)liter.Next() )
  564.     {
  565.         liter.RemoveCurrent();
  566.         
  567.         facet->GetContainingFacet(ev)->RemoveFacet(ev, facet);
  568.         delete facet;
  569.     }
  570. }
  571.  
  572. //------------------------------------------------------------------------------
  573. // GetQDFrameBounds
  574. //------------------------------------------------------------------------------
  575.  
  576. void GetQDFrameBounds(Environment* ev, ODFrame* frame, Rect* bounds)
  577. {
  578.     ODRect        boundingBox;
  579.     
  580.     TempODShape frameShape = frame->AcquireFrameShape(ev, kODNULL);
  581.     frameShape->GetBoundingBox(ev, &boundingBox);
  582.     
  583.     FixedToIntRect(boundingBox, *bounds);
  584. }
  585.  
  586. //-------------------------------------------------------------------------
  587. // ScrollProc
  588. //-------------------------------------------------------------------------
  589.  
  590. extern pascal void ScrollProc(ControlHandle control, short partCode)
  591. {
  592.     short delta;
  593.  
  594.     if (partCode == 0)
  595.         return;
  596.  
  597.     ScrollDataRec* sData = (ScrollDataRec*)(**control).contrlRfCon;
  598.         
  599.     switch(partCode) {
  600.         case kControlUpButtonPart:
  601.             delta = -1;
  602.             break;
  603.         case kControlDownButtonPart:
  604.             delta = 1;
  605.             break;
  606.         case kControlPageUpPart:
  607.             delta = -5;
  608.             break;
  609.         case kControlPageDownPart:
  610.             delta = 5;
  611.             break;
  612.         default:
  613.             delta = 0;
  614.     }
  615.     
  616.     short vScroll = GetControlValue(control);
  617.     
  618.     SetControlValue(control, vScroll + delta);
  619.     
  620.     vScroll = ((GetControlValue(control) - vScroll) * kListItemHeight);
  621.     
  622.     // Some movement occurred.
  623.     if ( vScroll != 0 )
  624.     {
  625.         ODFrame* frame = sData->frame;
  626.         TempODTransform intTransform = frame->AcquireInternalTransform(sData->ev, kODNULL);
  627.     
  628.         Point offset = intTransform->GetQDOffset(sData->ev);
  629.         offset.v -= vScroll;
  630.         intTransform->SetQDOffset(sData->ev, &offset);
  631.  
  632.         Rect sr;
  633.         GetQDFrameBounds(sData->ev, frame, &sr);
  634.         InsetRect(&sr,1,1);
  635.         sr.right -= 15;
  636.         
  637.         RgnHandle ur = NewRgn();
  638.         ScrollRect(&sr, 0, -vScroll, ur);
  639.         
  640.         TempODShape us = frame->CreateShape(sData->ev);
  641.         us->SetQDRegion(sData->ev, ur);
  642.         
  643.         frame->Invalidate(sData->ev, us, kODNULL);
  644.         frame->ChangeInternalTransform(sData->ev, intTransform, kODNULL);
  645.     }
  646. }
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.